package com.kfyang.manualgear.generator.impl.jdbc.orm;

import com.kfyang.manualgear.constant.TypeNameConstants;
import com.kfyang.manualgear.struct.EntityInfo;
import com.kfyang.manualgear.struct.FieldInfo;
import com.kfyang.manualgear.util.StringUtils;
import com.squareup.javapoet.MethodSpec;

import java.util.StringJoiner;

import static com.kfyang.manualgear.constant.Constants.*;
import static com.kfyang.manualgear.constant.StatementConstants.*;
import static com.kfyang.manualgear.generator.impl.jdbc.constant.StatementConstants.*;
import static com.kfyang.manualgear.generator.impl.jdbc.constant.SqlConstants.*;

public class InsertMethod extends AbstractMethod {

    protected InsertMethod(MethodSpec.Builder methodBuilder, EntityInfo entityInfo, boolean forOne) {
        super(methodBuilder, entityInfo, forOne);
    }

    @Override
    protected void prepareParameters() {
        methodBuilder.addStatement(NEW_PARAMETER_LIST,
            TypeNameConstants.LIST_OBJECT_TYPE, TypeNameConstants.ARRAY_LIST_TYPE);

        if (!forOne) {
            methodBuilder.beginControlFlow(FOR_ENTITY_LIST, entityInfo.entityTypeName);
        }
        for (FieldInfo fieldInfo : entityInfo.fieldInfos) {
            methodBuilder.addStatement(ADD_ENTITY_VALUE, StringUtils.toGetMethod(fieldInfo.field));
        }
        if (entityInfo.createTimeInfo != null) {
            methodBuilder.addStatement(ADD_NEW_OBJECT, TypeNameConstants.DATE_TYPE);
        }
        if (entityInfo.updateTimeInfo != null) {
            methodBuilder.addStatement(ADD_NEW_OBJECT, TypeNameConstants.DATE_TYPE);
        }
        if (!forOne) {
            methodBuilder.endControlFlow();
        }
    }

    @Override
    protected void prepareSql() {
        StringJoiner columnJoiner = new StringJoiner(COMMA);
        for (FieldInfo fieldInfo : entityInfo.fieldInfos) {
            columnJoiner.add(fieldInfo.col);
        }
        int parameterSize = entityInfo.fieldInfos.size();
        if (entityInfo.createTimeInfo != null) {
            columnJoiner.add(entityInfo.createTimeInfo.col);
            parameterSize++;
        }
        if (entityInfo.updateTimeInfo != null) {
            columnJoiner.add(entityInfo.updateTimeInfo.col);
            parameterSize++;
        }

        String inList = StringUtils.inList(parameterSize);
        String sqlStatement = SQL_DEFINE + INSERT_SQL +
            (forOne ? LITERAL_PLACEHOLDER + QUOTA : QUOTA + CONCAT + INSERT_LISTS);
        methodBuilder.addStatement(sqlStatement, entityInfo.tableName, columnJoiner, inList);
    }

    @Override
    public void addReturn() {
        methodBuilder.addStatement(RETURN_MODIFY_RESULT);
    }
}
